home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
lang
/
mc302
/
dosutil
/
cmos.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-03-18
|
4KB
|
150 lines
/*
* Program to save/restore/verify the CMOS data of an AT BIOS.
*
* Copyright 1991-1994 Dave Dunfield
* All rights reserved.
*
* Compile with: cc cmos -fop
*/
#include <stdio.h>
#define MAX_SIZE 128-0x10 /* Maximum potential size of CMOS ram */
unsigned char buffer1[MAX_SIZE], buffer2[MAX_SIZE], verbose = -1;
int size = 32, ignore[50]; icount = 0;
char *help[] = {
"\nUse: CMOS <command> <filename> [options]\n",
"command: Save - Save CMOS data to a file",
" Restore - Recover CMOS data from file",
" Verify - Compare CMOS data to file\n",
"options: -Q - QUIET, inhibit messages",
" I=value - Ignore byte at this offset (Verify)",
" S=value - Bytes of CMOS to SAVE (default 32)\n",
"Copyright 1991 Dave Dunfield",
"All rights reserved",
0 };
/*
* Main program
*/
main(argc, argv)
int argc;
char *argv[];
{
int i;
char *ptr;
FILE *fp;
if(argc < 3) {
for(i = 0; help[i]; ++i) {
fputs(help[i], stderr);
putc('\n', stderr); }
return; }
for(i=3; i < argc; ++i) {
ptr = argv[i];
switch((*ptr++ << 8) | *ptr++) {
case '-q' : /* Request QUIET mode */
case '-Q' :
verbose = 0;
break;
case 's=' : /* Specify size to save */
case 'S=' :
size = atoi(ptr);
break;
case 'i=' : /* Specify IGNORE bytes */
case 'I=' :
ignore[icount++] = atoi(ptr);
break;
default:
fputs("Invalid option: ", stderr);
fputs(argv[i], stderr);
return; } }
switch(*argv[1]) {
case 's' : /* Save CMOS data to a file */
case 'S' :
read_cmos(buffer1, 0x1000+size);
fp = fopen(argv[2], "wvqb");
fwrite(buffer1, size, fp);
fclose(fp);
message("CMOS data saved");
break;
case 'r' : /* Restore CMOS data from a file */
case 'R' :
fp = fopen(argv[2], "rvqb");
size = fread(buffer1, MAX_SIZE, fp);
fclose(fp);
write_cmos(buffer1, 0x1000+size);
message("CMOS data restored");
break;
case 'v' : /* Verify CMOS data with file */
case 'V' :
fp = fopen(argv[2], "rvqb");
size = fread(buffer2, MAX_SIZE, fp);
fclose(fp);
read_cmos(buffer1, 0x1000+size);
for(i=0; i < icount; ++i)
buffer1[ignore[i]] = buffer2[ignore[i]] = 0;
for(i=0; i < size; ++i) {
if(buffer1[i] != buffer2[i]) {
message("CMOS verify FAILED!!!");
exit(-1); } }
message("CMOS Data verified");
break;
default: /* Invalid command */
fputs("Unknown command: ", stderr);
fputs(argv[1], stderr);
return; }
}
/*
* Issue message to used only if "verbose" enabled
*/
message(string)
char *string;
{
if(verbose)
fputs(string, stdout);
}
/*
* Read data from the CMOS ram
*/
read_cmos(dest, addr_size) asm
{
MOV BX,6[BP] ; Get destination
MOV CX,4[BP] ; Get start/size
CLI ; Disallow interruptions
rdloop: MOV AL,CH ; Get address
OUT 70h,AL ; Write it
INC CH ; Advance address
IN AL,71h ; Read the data
MOV [BX],AL ; Write it in dest
INC BX ; Advance destination
DEC CL ; Reduce count
JNZ rdloop ; And continue
STI ; Allow interruptions
}
/*
* Write data to the CMOS ram
*/
write_cmos(source, addr_size) asm
{
MOV BX,6[BP] ; Get destination
MOV CX,4[BP] ; Get start/size
CLI ; Disallow interruptions
wrloop: MOV AL,CH ; Get address
OUT 70h,AL ; Write it
MOV AL,[BX] ; Get value to write
OUT 71h,AL ; Write it
INC CH ; Advance address
INC BX ; Advance destination
DEC CL ; Reduce count
JNZ wrloop ; And continue
STI ; Allow interruptions
}